{{>header}}
import 'dart:async';
import 'package:dio/dio.dart';
import 'package:built_value/serializer.dart';

{{#operations}}
{{#imports}}import '{{.}}';
{{/imports}}

class {{classname}} {

  final Dio _dio;

  final Serializers _serializers;

  const {{classname}}(this._dio, this._serializers);

  {{#operation}}
  /// {{{summary}}}
  ///
  /// {{{notes}}}
  Future<Response<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}>> {{nickname}}({{^hasRequiredParams}}{ {{/hasRequiredParams}}{{#requiredParams}}
    {{{dataType}}} {{paramName}},{{#-last}} { {{/-last}}{{/requiredParams}}{{#optionalParams}}
    {{{dataType}}} {{paramName}},{{/optionalParams}}
    CancelToken cancelToken,
    Map<String, dynamic> headers,
    Map<String, dynamic> extra,
    ValidateStatus validateStatus,
    ProgressCallback onSendProgress,
    ProgressCallback onReceiveProgress,
  }) async {
    final _request = RequestOptions(
      path: r'{{{path}}}'{{#pathParams}}.replaceAll('{' r'{{{baseName}}}' '}', {{{paramName}}}.toString()){{/pathParams}},
      method: '{{#lambda.uppercase}}{{httpMethod}}{{/lambda.uppercase}}',
      {{#isResponseFile}}
      responseType: ResponseType.bytes,
      {{/isResponseFile}}
      headers: <String, dynamic>{
        {{#httpUserAgent}}
        r'User-Agent': r'{{{.}}}',
        {{/httpUserAgent}}
        {{#headerParams}}
        {{^required}}{{^nullable}}if ({{{paramName}}} != null) {{/nullable}}{{/required}}r'{{baseName}}': {{paramName}},
        {{/headerParams}}
        ...?headers,
      },
      {{#hasQueryParams}}
      queryParameters: <String, dynamic>{
        {{#queryParams}}
        {{^required}}{{^nullable}}if ({{{paramName}}} != null) {{/nullable}}{{/required}}r'{{baseName}}': {{paramName}},
        {{/queryParams}}
      },
      {{/hasQueryParams}}
      extra: <String, dynamic>{
        'secure': <Map<String, String>>[{{^hasAuthMethods}}],{{/hasAuthMethods}}{{#hasAuthMethods}}
          {{#authMethods}}{
            'type': '{{type}}',
            'name': '{{name}}',{{#isApiKey}}
            'keyName': '{{keyParamName}}',
            'where': '{{#isKeyInQuery}}query{{/isKeyInQuery}}{{#isKeyInHeader}}header{{/isKeyInHeader}}',{{/isApiKey}}
          },{{/authMethods}}
        ],{{/hasAuthMethods}}
        ...?extra,
      },
      validateStatus: validateStatus,
      contentType: '{{^hasConsumes}}application/json{{/hasConsumes}}{{#hasConsumes}}{{#prioritizedContentTypes}}{{#-first}}{{{mediaType}}}{{/-first}}{{/prioritizedContentTypes}}{{/hasConsumes}}',
      cancelToken: cancelToken,
      onSendProgress: onSendProgress,
      onReceiveProgress: onReceiveProgress,
    );

    dynamic _bodyData;
    {{#hasFormParams}}

    _bodyData = {{#isMultipart}}FormData.fromMap({{/isMultipart}}<String, dynamic>{
      {{#formParams}}
      {{^required}}{{^nullable}}if ({{{paramName}}} != null) {{/nullable}}{{/required}}r'{{{baseName}}}': {{#isFile}}MultipartFile.fromBytes({{{paramName}}}, filename: r'{{{baseName}}}'){{/isFile}}{{^isFile}}encodeFormParameter(_serializers, {{{paramName}}}, const FullType({{^isContainer}}{{{baseType}}}{{/isContainer}}{{#isContainer}}Built{{#isMap}}Map{{/isMap}}{{#isArray}}{{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isArray}}, [{{#isMap}}FullType(String), {{/isMap}}FullType({{{baseType}}})]{{/isContainer}})){{/isFile}},
      {{/formParams}}
    }{{#isMultipart}}){{/isMultipart}};
    {{/hasFormParams}}
    {{#bodyParam}}

    {{#isPrimitiveType}}
    _bodyData = {{paramName}};
    {{/isPrimitiveType}}
    {{^isPrimitiveType}}
    {{#isContainer}}
    const _type = FullType(Built{{#isMap}}Map{{/isMap}}{{#isArray}}{{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isArray}}, [{{#isMap}}FullType(String), {{/isMap}}FullType({{{baseType}}})]);
    _bodyData = _serializers.serialize({{paramName}}, specifiedType: _type);
    {{/isContainer}}
    {{^isContainer}}
    const _type = FullType({{{baseType}}});
    _bodyData = _serializers.serialize({{paramName}}, specifiedType: _type);
    {{/isContainer}}
    {{/isPrimitiveType}}
    {{/bodyParam}}

    final _response = await _dio.request<dynamic>(
      _request.path,
      data: _bodyData,
      options: _request,
    );
    {{#returnType}}

    {{#isResponseFile}}
    final {{{returnType}}} _responseData = _response.data as {{{returnType}}};
    {{/isResponseFile}}
    {{^isResponseFile}}
    {{#returnSimpleType}}
    {{#returnTypeIsPrimitive}}
    final {{{returnType}}} _responseData = _response.data as {{{returnType}}};
    {{/returnTypeIsPrimitive}}
    {{^returnTypeIsPrimitive}}
    const _responseType = FullType({{{returnType}}});
    final _responseData = _serializers.deserialize(
      _response.data,
      specifiedType: _responseType,
    ) as {{{returnType}}};
    {{/returnTypeIsPrimitive}}
    {{/returnSimpleType}}
    {{^returnSimpleType}}
    const _responseType = FullType(Built{{#isArray}}{{#uniqueItems}}Set{{/uniqueItems}}{{^uniqueItems}}List{{/uniqueItems}}{{/isArray}}{{#isMap}}Map{{/isMap}}, [{{#isMap}}FullType(String), {{/isMap}}FullType({{{returnBaseType}}})]);
    final {{{returnType}}} _responseData = _serializers.deserialize(
      _response.data,
      specifiedType: _responseType,
    ) as {{{returnType}}};
    {{/returnSimpleType}}
    {{/isResponseFile}}

    return Response<{{{returnType}}}>(
      data: _responseData,
      headers: _response.headers,
      isRedirect: _response.isRedirect,
      request: _response.request,
      redirects: _response.redirects,
      statusCode: _response.statusCode,
      statusMessage: _response.statusMessage,
      extra: _response.extra,
    );{{/returnType}}{{^returnType}}
    return _response;{{/returnType}}
  }

  {{/operation}}
}
{{/operations}}
